 /** 
 * @addtogroup nmea
 * nmea
 * @brief NMEA报文解析器
 * @par 示例
 * @code
    // 定义一些常见的测试场景
    struct {
        const char *sentence; 
        int token_count; 
        TNmeaRmc rmc;
    } 
    
    
    test_case[] = {

        // 正常
        {
            "$GPRMC,023543.00,A,2308.28715,N,11322.09875,E,0.195,,240213,,,A*78",
            13,
            {
                NMEA_RMC_HAS_STATUS | NMEA_RMC_HAS_TIMESTAMP | NMEA_RMC_HAS_LAT_LONG | NMEA_RMC_HAS_SPEED | NMEA_RMC_HAS_MODE,  ///< flag
                kNmeaDataStatusValid, ///< satus
                kNmeaPositionSysModeAutonomous, ///< mode 
                1361673343,  ///< utc 
                231381191,   ///< lat
                1133683125,  ///< long 
                361,         ///< speed
                0            ///< bearing 
            }
        },

        // 切换半球
        // Latitude, N->S
        // Longitude, E->W
        {
            "$GPRMC,023543.00,A,2308.28715,S,11322.09875,W,0.195,,240213,,,A*78",
            13,
            {
                NMEA_RMC_HAS_STATUS | NMEA_RMC_HAS_TIMESTAMP | NMEA_RMC_HAS_LAT_LONG | NMEA_RMC_HAS_SPEED | NMEA_RMC_HAS_MODE, ///< flag
                kNmeaDataStatusValid,  ///< satus
                kNmeaPositionSysModeAutonomous,  ///< mode
                1361673343, ///< utc 
                -231381191, ///< lat 
                -1133683125,///< long
                361,        ///< speed 
                0           ///< bearing 
            }
        },
        
        // 无半球标识
        // Latitude, N->S
        // Longitude, E->W
        {
            "$GPRMC,023543.00,A,2308.28715,,11322.09875,,0.195,,240213,,,A*78",
            13,
            {
                NMEA_RMC_HAS_STATUS | NMEA_RMC_HAS_TIMESTAMP | NMEA_RMC_HAS_LAT_LONG | NMEA_RMC_HAS_SPEED | NMEA_RMC_HAS_MODE, ///< flag
                kNmeaDataStatusValid,  ///< satus
                kNmeaPositionSysModeAutonomous,  ///< mode
                1361673343, ///< utc 
                -231381191, ///< lat 
                -1133683125,///< long
                361,        ///< speed 
                0           ///< bearing 
            }
        },

        // 错误半球
        // Latitude, N->X
        // Longitude, E->Y
        {
            "$GPRMC,023543.00,A,2308.28715,X,11322.09875,Y,0.195,,240213,,,A*78",
            13,
            {
                NMEA_RMC_HAS_STATUS | NMEA_RMC_HAS_TIMESTAMP | NMEA_RMC_HAS_LAT_LONG | NMEA_RMC_HAS_SPEED | NMEA_RMC_HAS_MODE, ///< flag
                kNmeaDataStatusValid,  ///< satus
                kNmeaPositionSysModeAutonomous,  ///< mode
                1361673343, ///< utc 
                -231381191, ///< lat 
                -1133683125,///< long
                361,        ///< speed 
                0           ///< bearing 
            }
        },

        // 异常:经纬度带符号位
        {
            "$GPRMC,023543.00,A,-2308.28715,X,-11322.09875,Y,0.195,,240213,,,A*78",
            13,
            {
                NMEA_RMC_HAS_STATUS | NMEA_RMC_HAS_TIMESTAMP | NMEA_RMC_HAS_LAT_LONG | NMEA_RMC_HAS_SPEED | NMEA_RMC_HAS_MODE, ///< flag
                kNmeaDataStatusValid,  ///< satus
                kNmeaPositionSysModeAutonomous,  ///< mode
                1361673343, ///< utc 
                -231381191, ///< lat 
                -1133683125,///< long
                361,        ///< speed 
                0           ///< bearing 
            }
        },

        // 全精度
        {
            "$GPRMC,023543.00,A,2308,X,11322,Y,0.195,,240213,,,A*78",
            13,
            {
                NMEA_RMC_HAS_STATUS | NMEA_RMC_HAS_TIMESTAMP | NMEA_RMC_HAS_LAT_LONG | NMEA_RMC_HAS_SPEED | NMEA_RMC_HAS_MODE, ///< flag
                kNmeaDataStatusValid,  ///< satus
                kNmeaPositionSysModeAutonomous,  ///< mode
                1361673343, ///< utc 
                -231381191, ///< lat 
                -1133683125,///< long
                361,        ///< speed 
                0           ///< bearing 
            }
        },
     };

    TNmeaTokenizer tok;
    TNmeaRmc rmc;
    for (int i = 0; i < sizeof(test_case) / sizeof(test_case[0]); i++) {
        const char *ss = test_case[i].sentence;
        const char *se = ss + strlen(ss);

        int ret = NmeaTokenizerInit(&tok, ss, se);
        CuAssert(tc, "tokenizer 字段数量错误", test_case[i].token_count == ret);

        memset(&rmc, 0, sizeof(rmc));
        
        // 解析原始报文，获取的解析结果存放在rmc中
        NmeaParseRmc(&tok, &rmc);
        
        // 判断解析得到的结果是否正确
        CuAssert(tc, "tokenizer flags解析错误", test_case[i].rmc.flags == rmc.flags);
        CuAssert(tc, "tokenizer data_status解析错误", test_case[i].rmc.data_status == rmc.data_status);
        CuAssert(tc, "tokenizer mode解析错误", test_case[i].rmc.mode == rmc.mode);
        CuAssert(tc, "tokenizer bearing解析错误", test_case[i].rmc.bearing == rmc.bearing);
        CuAssert(tc, "tokenizer timestamp解析错误", test_case[i].rmc.time_utc == rmc.time_utc);
        CuAssert(tc, "tokenizer speed解析错误", test_case[i].rmc.speed == rmc.speed);
        CuAssert(tc, "tokenizer latitude解析错误", test_case[i].rmc.latitude == rmc.latitude);
        CuAssert(tc, "tokenizer longitude解析错误", test_case[i].rmc.longitude == rmc.longitude);
    }
    
 * @endcode
 * @{
 */
 
/**
 * @file nmea_parser.h
 * @brief NMEA报文解析器
 * 
 * @author lzl(lzl@hopechart.com)
 * @date 2019-9-19
 * @version 1.1
 * @copyright 杭州鸿泉物联网技术股份有限公司
 * 
 * @par 修订日志
 * <table>
 * <tr><th>Date <th>Version <th> Author <th> Descripton
 * <tr><td>2019-9-19 <td>1.1 <td> liuzl <td> 建立初始版本
 * </table>
 * 
 */
#ifndef _HUBS_LIB_NMEA_PARSER_H_
#define _HUBS_LIB_NMEA_PARSER_H_

#include "nmea/nmea_types.h"
#include "nmea/nmea_tokenizer.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 解析地址域
 * 
 * @param t 分词器对象
 * @param addr 
 * 
 * @return bool 
 */
bool NmeaParseAddr(TNmeaTokenizer *t, TNmeaAddrField *addr);

/**
 * 解析RMC信息
 * 
 * @param t 分词器对象
 * @param rmc RMC信息结构
 */
int NmeaParseRmc(TNmeaTokenizer *t, TNmeaRmc *rmc);

/**
 * 解析GGA信息
 * 
 * @param t 分词器对象
 * @param gga GGA信息结构
 */
int NmeaParseGga(TNmeaTokenizer *t, TNmeaGga *gga);

/**
 * 解析GSA信息
 * 
 * @param t 分词器对象
 * @param gsa GSA信息结构
 */
int NmeaParseGsa(TNmeaTokenizer *t, TNmeaGsa *gsa);

/**
 * 解析GSV信息
 * 
 * @param t 分词器对象
 * @param gsv GSV信息结构
 */
int NmeaParseGsv(TNmeaTokenizer *t, TNmeaGsv *gsv);

#ifdef __cplusplus
}
#endif

#endif//_HUBS_LIB_NMEA_PARSER_H_

/**
 * @} 
 */
 
